#ifndef __OBSERVER_H__
#define __OBSERVER_H__
#include <iostream>
#include <string>
#include <memory>
#include <list>

class Observer;

class Subject{
protected:
    std::list<Observer*> m_observers;
public:
    virtual ~Subject(){m_observers.clear();}
    virtual void attach(Observer* obs) = 0;
    virtual void detach(Observer* obs) = 0;
    virtual void notify() = 0;
};

class ConcreteSubject : public Subject{
public:
    virtual void attach(Observer* obs);
    virtual void detach(Observer* obs);
    void notify();
};

class Observer{
protected:
    std::string m_name;
    std::shared_ptr<Subject> m_sub;
public:
    virtual ~Observer(){}
    virtual void update() = 0;
     std::string getName(){
        return m_name;
    }
};

class ConcreteObserver : public Observer ,public std::enable_shared_from_this<ConcreteObserver> {
public:
    ConcreteObserver(const std::string& name,std::shared_ptr<Subject> subject){
        m_name = name;
        m_sub = subject;
        m_sub->attach(this);
    }
   
    virtual void update();

};

#endif